dojo.require("dojox.cometd");
//dojo.require("dojox.cometd.ack");
dojo.require("dojoscratch.Board");
dojo.require("dijit.Toolbar");

dojo.require("dojoscratch.LineCommand");
dojo.require("dojoscratch.RectangleCommand");
dojo.require("dojoscratch.CircleCommand");
dojo.require("dojoscratch.TextCommand");
dojo.require("dojoscratch.PathCommand");
dojo.require("dojoscratch.DotCommand");

var scratchCometd = {
	init: function() {
		eval ("var scratchcrewCometdUrl = \"" + dojo.byId("boardForm:cometdUrl").value + "\"");
		var boardId = dojo.byId("boardForm:boardIdInputText").value;
		this._boardChannel = "/scratchcrew/board/" + boardId;
		
		dojox.cometd.ackEnabled = false;
		dojox.cometd.init(scratchcrewCometdUrl);
		this._connected = true;
		
		this._imagesAvailable = new Object();

		// Subscribe board to scratch channel
		dojox.cometd.startBatch();
		dojox.cometd.subscribe(this._boardChannel, scratchCometd, "_handleBoardMessage");
		dojox.cometd.publish(this._boardChannel, {
			type: "join",
			joinType: "join"
		});
		dojox.cometd.endBatch();

		// handle cometd failures while in the board
		if (scratchCometd._meta) {
			dojo.unsubscribe(scratchCometd._meta, null, null);
		}
		scratchCometd._meta = dojo.subscribe("/cometd/meta", this,
						"_handleMetaMessage");

		this._activatedSubscribtion = 
			dojo.subscribe("activated", this, "_alignToolbar");
	},
	leave: function() {
		if (scratchCometd._meta) {
			dojo.unsubscribe(scratchCometd._meta);
		}
		scratchCometd._meta = null;
		// Unsubsribe board from scratch channel.
		dojox.cometd.startBatch();
		dojox.cometd.unsubscribe(this._boardChannel, scratchCometd, "_handleBoardMessage");
		dojox.cometd.publish(this._boardChannel, {
			type : "leave"
		});
		dojox.cometd.endBatch();
		// Disconnect from commetd
		dojox.cometd.disconnect();
	},
	_handleMetaMessage: function (e) {
		if (e.action == "handshake") {
			if (e.reestablish) {
				if (e.successful) {
					dojox.cometd.subscribe(
							this._boardChannel, 
							scratchCometd, "_handleBoardMessage");
					dojox.cometd.publish(
							this._boardChannel, {
								type: "join",
								joinType: "re-joined"
							});
				}
				scratchCometd._handleBoardMessage( {
							data : {
								type: "join",
								user : "SERVER",
								message : "handshake "
										+ e.successful ? "Handshake OK"
										: "Failed"
							}
						});
			}
		} else if (e.action == "connect") {
			if (e.successful && !this._connected) {
				scratchCometd._handleBoardMessage( {
					data : {
						type: "join",
						user : "SERVER",
						joinType : "re-joined"
					}
				});
			}
			if (!e.successful && this._connected) {
				scratchCometd._handleBoardMessage( {
					data : {
						type : "leave",
						user : "SERVER",
					}
				});
			}
			this._connected = e.successful;
		}
	},
	_alignToolbar: function(activeScratch) {
		var toolbar = dojo.byId("toolbar");
		var box = activeScratch.getTransformedBoundingBox();
		var board = dojo.byId("boardForm:board");
		
		var top = box.y + board.offsetTop - toolbar.clientHeight - 10 ;
		var left = box.x + board.offsetLeft + box.width - toolbar.clientWidth + 10;
		toolbar.style.position = "absolute";
		toolbar.style.top = top+"px";
		toolbar.style.left = left+"px";
		toolbar.style.display = "";
	},
	_handleBoardMessage: function(message) {
		if (!message.data) {
			console.debug("bad message format " + message);
			return;
		}
		if (message.data instanceof Array) {
			console.debug("message.data is array");
		} else if (message.data.type) {
			console.debug("new board message with type '" + message.data.type + "'");
			if (message.data.type == "initBoard") {
				this._initImagesAvailable(message.data);
				this._board = new dojoscratch.Board("boardForm:board", message.data);
				dojo.query("#lineCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [new dojoscratch.LineCommand(dojo.byId("boardForm:board"))]);
						});
				dojo.query("#rectangleCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [new dojoscratch.RectangleCommand(dojo.byId("boardForm:board"))]);
						});
				dojo.query("#circleCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [new dojoscratch.CircleCommand(dojo.byId("boardForm:board"))]);
						});
				dojo.query("#pathCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [new dojoscratch.PathCommand(dojo.byId("boardForm:board"))]);
						});
                dojo.query("#dotCommand").onclick(
                        function(event) {
                            dojo.publish("changeActiveCommand", [new dojoscratch.DotCommand(dojo.byId("boardForm:board"))]);
                        });
				dojo.query("#textCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [new dojoscratch.TextCommand(dojo.byId("boardForm:board"))]);
						});						
				dojo.query("#clearCommand").onclick(
						function(event) {
							dojo.publish("changeActiveCommand", [null]);
						});
				dojo.query("#toggleScale").onclick(
						function(event) {
							console.debug(event.target.className);
							if(event.target.className=="Button ToggledButton") {
								//stop scaling
								event.target.className = "Button";

								dojo.publish("changeScaleMode", [false]);
							} else {
								//start scaling
								event.target.className = "Button ToggledButton";

								dojo.publish("changeScaleMode", [true]);
							}
						});
				dojo.connect(dojo.byId("toolbar.remove"),"onclick",function(event) {
					//TODO i18n
					if (confirm("Are you sure you wish to delete scratch?")) {
						scratchCometd._board.sendRemoveActiveScratch();
					}
				});
				dojo.connect(
						dojo.byId("toolbar.sendToBack"), "onclick",
						function(event) {
							scratchCometd._board.sendChangeZIndexOfActiveScratch(0);
						});
				dojo.connect(dojo.byId("toolbar.bringToFront"), "onclick",
						function(event) {
					scratchCometd._board.sendChangeZIndexOfActiveScratch(-1);
				});
			} else if (message.data.type == "createScratch") {
				console.debug(message.data.content);
				this._board.createShape(message.data.content);
				this._addImageAvailable(message.data.content, true);
			} else if (message.data.type == "removeScratch") {
				this._board.removeScratch(message.data.scratchId);
				dojo.byId("toolbar").style.display = "none";
			} else if (message.data.type == "changeZIndex") {
				this._board.changeZIndex(message.data.scratchId, 
						message.data.zIndex);
			} else if (message.data.type == "transformScratch") {
				this._board.transformScratch(message.data);
			} else if (message.data.type == "transformText") {
				this._board.transformText(message.data);
			} else if (message.data.type == "pointing") {
				this._board.drawPointing(message.data.content);
			} else {
				console.debug("Unknown message type " + type + " :");
				console.debug(message);
			}
		} else {
			console.debug("Unknown message:");
			console.debug(message);
		}
	},
	_addImageAvailable: function(scratch, rerender) {
		console.debug(scratch);
		if ("image" == scratch.staticData.shape.type) {
			this._imagesAvailable[scratch.staticData.shape.src] = scratch.id;
			if (rerender) {
				this._rerenderImagesAvailable();
			}
		}
	},
	_initImagesAvailable: function(data) {
		var initScratches =  data.uiData.scratches;
		console.debug("initing images");
		for(i = 0; i < initScratches.length; i++) {
			console.debug(initScratches[i]);
			this._addImageAvailable(initScratches[i]);
		}
		this._rerenderImagesAvailable();
	},
	_rerenderImagesAvailable: function() {
		var result = "<ul>";

		for (imageSrc in this._imagesAvailable) {
			result += "<li>" +
				this._renderImageCreator(imageSrc) + 
				"</li>";
		}

		result += "</ul>";
		console.debug(result);
		dojo.byId("imagesAvailable").innerHTML = result;

	},
	_renderImageCreator: function(imageSrc) {
		var imgTag = "<img src='" + 
			imageSrc + "' height='40' width='40' />";
		var result = 
			"<a href='javascript:scratchCometd._board.createImageShape(\"" +
				imageSrc + "\")'>" + imgTag +"</a>";
		return result;
	}

};

dojo.addOnLoad(scratchCometd, "init");
dojo.addOnUnload(scratchCometd, "leave");
